package com.ruoyi.iot.task;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.iot.service.DeviceAlarmRecordService;
import com.ruoyi.iot.service.HostDeviceMetricsService;
import com.ruoyi.iot.service.IotMetricExtractService;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * IoTDB 统计抽取定时任务
 */
@Component("iotMetricExtractTask")
public class IotMetricExtractTask {

    private static final Logger log = LoggerFactory.getLogger(IotMetricExtractTask.class);

    private final IotMetricExtractService extractService;
    private final HostDeviceMetricsService hostDeviceMetricsService;
    private final DeviceAlarmRecordService alarmRecordService;

    public IotMetricExtractTask(IotMetricExtractService extractService,
                                HostDeviceMetricsService hostDeviceMetricsService,
                                DeviceAlarmRecordService alarmRecordService) {
        this.extractService = extractService;
        this.hostDeviceMetricsService = hostDeviceMetricsService;
        this.alarmRecordService = alarmRecordService;
    }

    /**
     * 抽取所有窗口数据（温度、电气、告警、故障）。
     */
    public void extractAll() {
        /*List<Map<String, Object>> devices = queryAllDevices();
        if (CollectionUtils.isEmpty(devices)) {
            log.info("extractAll 未查询到任何设备，跳过执行");
            return;
        }
        for (Map<String, Object> device : devices) {
            String hostDeviceId = MapUtils.getString(device, "device_id");
            if (StringUtils.isNotBlank(hostDeviceId)) {
                execute(hostDeviceId, extractService::syncTemperatureWindows);
                execute(hostDeviceId, extractService::syncAlarmWindows);
                execute(hostDeviceId, extractService::syncFaultWindows);
                execute(hostDeviceId, extractService::syncFaultRecords);
            }
            String cabinetDeviceId = MapUtils.getString(device, "device_kg_id");
            if (StringUtils.isNotBlank(cabinetDeviceId)) {
                execute(cabinetDeviceId, extractService::syncElectricalWindows);
            }
        }*/
    }

    /**
     * 抽取温度窗口数据。
     */
    public void extractTemperature() {
        for (String deviceId : resolveDeviceIds()) {
            execute(deviceId, extractService::syncTemperatureWindows);
        }
    }

    /**
     * 抽取电气窗口数据（使用 device_kg_id）。
     */
    public void extractElectrical() {
        for (String deviceId : resolveCabinetIds()) {
            execute(deviceId, extractService::syncElectricalWindows);
        }
    }

    /**
     * 抽取告警窗口数据。
     */
    public void extractAlarm() {
        String area = RuoYiConfig.getArea();
        boolean isJht = StringUtils.equals(area, "jht");
        if (isJht) {
            for (String deviceId : resolveCabinetIds()) {
                execute(deviceId, extractService::syncAlarmWindows);
            }
        }
        else {
            for (String deviceId : resolveDeviceIds()) {
                execute(deviceId, extractService::syncAlarmWindows);
            }
        }



    }

    /**
     * 抽取故障窗口数据。
     */
    public void extractFault() {
        String area = RuoYiConfig.getArea();
        boolean isJht = StringUtils.equals(area, "jht");
        if (isJht) {
            for (String deviceId : resolveCabinetIds()) {
                execute(deviceId, extractService::syncFaultWindows);
            }
        }
        else {
            for (String deviceId : resolveDeviceIds()) {
                execute(deviceId, extractService::syncFaultWindows);
            }
        }
    }

    /**
     * 抽取故障明细记录。
     */
    public void extractFaultRecord() {
        for (String deviceId : resolveDeviceIds()) {
            execute(deviceId, extractService::syncFaultRecords);
        }
    }

    /**
     * 同步最新告警记录到数据库
     */
    public void syncAlarmRecords() {
        String area = RuoYiConfig.getArea();
        boolean isJht = StringUtils.equals(area, "jht");
        if (isJht) {
            for (String deviceId : resolveCabinetIds()) {
                execute(deviceId, alarmRecordService::syncLatestRecords);
            }
        }
        else {
            for (String deviceId : resolveDeviceIds()) {
                execute(deviceId, alarmRecordService::syncLatestRecords);
            }
        }
    }

    private void execute(String deviceId, Consumer<String> action) {
        if (StringUtils.isBlank(deviceId)) {
            return;
        }
        try {
            action.accept(deviceId);
        } catch (ServiceException ex) {
            log.warn("执行IoTDB抽取任务失败, deviceId={}, msg={}", deviceId, ex.getMessage());
            throw ex;
        } catch (Exception ex) {
            log.error("执行IoTDB抽取任务异常, deviceId={}", deviceId, ex);
            throw ex;
        }
    }

    private List<Map<String, Object>> queryAllDevices() {
        return hostDeviceMetricsService.queryAllMainCabinetMetrics();
    }

    private List<String> resolveDeviceIds() {
        return queryAllDevices().stream()
            .map(row -> MapUtils.getString(row, "device_id"))
            .filter(StringUtils::isNotBlank)
            .distinct()
            .collect(Collectors.toList());
    }

    private List<String> resolveCabinetIds() {
        return queryAllDevices().stream()
            .map(row -> MapUtils.getString(row, "device_kg_id"))
            .filter(StringUtils::isNotBlank)
            .distinct()
            .collect(Collectors.toList());
    }
}
